package com.wie.staffhubpro.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wie.staffhubpro.constant.MessageConstant;
import com.wie.staffhubpro.domain.dto.ProjectDTO;
import com.wie.staffhubpro.domain.dto.ProjectEmpDTO;
import com.wie.staffhubpro.domain.entity.Project;
import com.wie.staffhubpro.domain.entity.ProjectDept;
import com.wie.staffhubpro.domain.entity.ProjectDetail;
import com.wie.staffhubpro.domain.entity.ProjectEmp;
import com.wie.staffhubpro.domain.vo.ProjectVO;
import com.wie.staffhubpro.exception.DataErrorException;
import com.wie.staffhubpro.exception.EmployeeNotInProjectException;
import com.wie.staffhubpro.exception.EmployeesNotAssignedYetException;
import com.wie.staffhubpro.mapper.ProjectDeptMapper;
import com.wie.staffhubpro.mapper.ProjectEmpMapper;
import com.wie.staffhubpro.service.ProjectService;
import com.wie.staffhubpro.mapper.ProjectMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

/**
* @author WiedersehenM
* @description 针对表【project】的数据库操作Service实现
* @createDate 2025-06-26 21:48:34
*/
@Service
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project>
    implements ProjectService{

    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private ProjectDeptMapper projectDeptMapper;
    @Autowired
    private ProjectEmpMapper projectEmpMapper;

    /**
     * 查询所有项目
     */
    public List<ProjectVO> listProject() {
        List<ProjectVO> projectVOList = projectMapper.selectProjectVOList();
        return projectVOList;
    }

    /**
     * 根据id查询项目
     */
    public ProjectDetail getByProjId(Integer projectId) {
        // 根据项目 id 查询项目
        Project project = projectMapper.selectById(projectId);
        // 查询负责部门的 id
        QueryWrapper<ProjectDept> deptWrapper = new QueryWrapper<>();
        deptWrapper.eq("proj_id", projectId);
        List<ProjectDept> projectDeptList = projectDeptMapper.selectList(deptWrapper);
        if (projectDeptList == null || projectDeptList.isEmpty()) {
            throw new DataErrorException(MessageConstant.DATA_ERROR);
        }
        ProjectDept projectDept = projectDeptList.get(0);
        // 查询参与项目的员工
        QueryWrapper<ProjectEmp> empWrapper = new QueryWrapper<>();
        empWrapper.eq("proj_id", projectId)
                .orderByAsc("responsibility");
        List<ProjectEmp> projectEmpList = projectEmpMapper.selectList(empWrapper);
        if (projectEmpList == null || projectEmpList.isEmpty()) {
            throw new EmployeesNotAssignedYetException(MessageConstant.EMPLOYEES_NOT_ASSIGNED_YET);
        }
        // 找到项目经理
        ProjectEmp projMan = projectEmpList.get(0);
        // 向 projectDetail 中填充数据
        ProjectDetail projectDetail = new ProjectDetail();
        BeanUtils.copyProperties(project, projectDetail);
        projectDetail.setDeptId(projectDept.getDeptId());
        projectDetail.setProjMan(projMan.getEmpId());
        projectDetail.setEmpList(projectEmpList);
        return projectDetail;
    }

    /**
     * 新增项目
     */
    @Transactional
    public void add(ProjectDTO projectDTO) {
        // 向 project 表中添加信息
        Project project = new Project();
        if (projectDTO.getStartDate() == null) {
            project.setStartDate(LocalDate.now());
        } else {
            project.setStartDate(projectDTO.getStartDate());
        }
        project.setProjectName(projectDTO.getProjectName());
        project.setProjectDesc(projectDTO.getProjectDesc());
        project.setEndDate(projectDTO.getEndDate());
        project.setStatus(projectDTO.getStatus());
        project.setCreateTime(LocalDateTime.now());
        project.setUpdateTime(LocalDateTime.now());
        projectMapper.insert(project);
        // 查找新增项目的 id
        QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        List<Project> projectList = projectMapper.selectList(queryWrapper);
        Integer projId = projectList.get(0).getId();
        // 向 project_emp 表中添加信息
        ProjectEmp projectEmp = new ProjectEmp().builder()
                .empId(projectDTO.getProjMan())
                .projId(projId)
                .responsibility(0)
                .joinDate(LocalDate.now())
                .build();
        projectEmpMapper.insert(projectEmp);
        // 向 project_dept 表中添加信息
        ProjectDept projectDept = new ProjectDept().builder()
                .projId(projId)
                .deptId(projectDTO.getDeptId())
                .build();
        projectDeptMapper.insert(projectDept);
    }

    /**
     * 更新项目信息
     */
    @Transactional
    public void alter(ProjectDTO projectDTO) {
        // 更新 project 表中的信息
        Project project = new Project().builder()
                .id(projectDTO.getProjId())
                .endDate(projectDTO.getEndDate())
                .projectName(projectDTO.getProjectName())
                .projectDesc(projectDTO.getProjectDesc())
                .status(projectDTO.getStatus())
                .updateTime(LocalDateTime.now())
                .build();
        projectMapper.updateById(project);
    }

    /**
     * 给项目添加员工
     */
    public void addEmp(ProjectEmpDTO projectEmpDTO) {
        ProjectEmp projectEmp = new ProjectEmp().builder()
                .projId(projectEmpDTO.getProjId())
                .empId(projectEmpDTO.getEmpId())
                .responsibility(1)
                .joinDate(LocalDate.now())
                .build();
        projectEmpMapper.insert(projectEmp);
    }

    /**
     * 从项目中删除员工
     */
    public void delEmp(ProjectEmpDTO projectEmpDTO) {
        Integer empId = projectEmpDTO.getEmpId();
        Integer projId = projectEmpDTO.getProjId();
        ProjectEmp projectEmp = projectEmpMapper.delEmp(empId, projId);
        if (projectEmp == null) {
            throw new EmployeeNotInProjectException(MessageConstant.EMPLOYEE_NOT_IN_PROJECT);
        }
        projectEmp.setLeaveDate(LocalDate.now());
        projectEmpMapper.updateById(projectEmp);
    }
}




